﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using UnityEngine;

public abstract class CardBase : MonoBehaviour
{

    private float start_scale;
    protected bool isfocus = false;
    protected float focus_scale;

    public string imagePath;
    protected float currentTargetScale;
    protected float currentTargetShadowAlpha;
    protected float currentShadowAlpha;
    private float scale_tolorence = 10;
    private Vector3 img_plane_startscale;
    private float start_scale_tolorence = 1;

    protected Texture lastTex;

    protected MeshRenderer Render
    {
        get
        {
            return GetComponentInChildren<MeshRenderer>();
        }
    }

    protected bool CutOut
    {
        set
        {
            Render.material.SetFloat("cutoutflag", value ? 1 : -1);
        }
    }

    protected bool FlipUVY
    {
        set
        {
            Render.material.SetFloat("flipflag", value ? 1 : -1);
        }
    }

    protected virtual void Awake()
    {
        start_scale = transform.localScale.x;
        focus_scale = start_scale * 1.3f;
    }

    protected virtual void Start()
    {
        if (string.IsNullOrEmpty(imagePath)) return;

        AVProVideoPlayerMgr.Instance.Stop();

        if (imagePath.EndsWith(".png"))
        {
            // var image = Image.FromFile(imagePath);
            // var framBitmap = new Bitmap(image.Width, image.Height);
            // using (var newGraphics = System.Drawing.Graphics.FromImage(framBitmap))
            // {
            //     newGraphics.DrawImage(image, Point.Empty);
            // }
            // var frameTexture2D = new Texture2D(framBitmap.Width, framBitmap.Height, TextureFormat.ARGB32, false);
            // frameTexture2D.LoadImage(BitmapToByte(framBitmap));
            // frameTexture2D.Apply();
            // Debug.Log(imagePath);
            StartCoroutine(Res.LoadExternalTexture(imagePath, tex =>
            {
                FlipUVY = false;
                CutOut = false;
                Render.material.mainTexture = tex;
                FixSize(new Vector2(tex.width, tex.height));
                lastTex = tex;
            }));


        }
        else if (imagePath.EndsWith(".mp4"))
        {
            PlayVideo(imagePath);
        }

    }

    public void PlayVideo(string videopath, bool isDefault = true)
    {
        bool issucess = AVProVideoPlayerMgr.Instance.PlayVideo(RenderHeads.Media.AVProVideo.MediaPlayer.FileLocation.AbsolutePathOrURL, videopath, true);
        if (issucess)
        {
            AVProVideoPlayerMgr.Instance.ready_callback = () =>
            {
                FlipUVY = AVProVideoPlayerMgr.Instance.Mediaplayer.TextureProducer.RequiresVerticalFlip();
                CutOut = true;
                Texture tex = AVProVideoPlayerMgr.Instance.mainTexture;
                Render.material.mainTexture = tex;
                FixSize(new Vector2(tex.width,tex.height));
                lastTex = tex;
            };
        }
    }

    private byte[] BitmapToByte(Bitmap bitmap)
    {
        using (var stream = new MemoryStream())
        {
            bitmap.Save(stream, ImageFormat.Png);
            var data = new byte[stream.Length];
            stream.Seek(0, SeekOrigin.Begin);
            stream.Read(data, 0, Convert.ToInt32(stream.Length));
            return data;
        }
    }

    protected virtual void FixSize(Vector2 texSize)
    {
        Vector2 finalQuadSize;
        float hwRadio = texSize.y / texSize.x;
        scale_tolorence = AppDataManager.Instance.GetCurrentPackageInfo().packageConfig.scaling_tolerance;
        if (hwRadio >= 1)
        {
            finalQuadSize = new Vector2(scale_tolorence / hwRadio, scale_tolorence);
        }
        else
        {
            finalQuadSize = new Vector2(scale_tolorence, scale_tolorence * hwRadio);
        }

        start_scale_tolorence = scale_tolorence;
        img_plane_startscale = transform.Find("Image").localScale = finalQuadSize;
    }

    public virtual void Focus(Vector3 mousePos)
    {

        Vector3 focusPoint = Camera.main.ScreenToWorldPoint(mousePos);
        Debug.DrawLine(transform.position, focusPoint);
        transform.LookAt(focusPoint);

    }

    private bool IsHitCardObject(Vector3 mousePos)
    {
        Ray ray = Camera.main.ScreenPointToRay(mousePos);
        //Debug.DrawLine(ray.origin, ray.direction * 100);
        return Physics.Raycast(ray, Mathf.Infinity, 1 << LayerMask.NameToLayer("Card"));
    }

    protected virtual void FixedUpdate()
    {

        PackageData packageData = AppDataManager.Instance.GetCurrentPackageInfo();
        if (packageData == null) return;

        bool isEnterView = false;
        Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1);
        Vector2 viewpos = Camera.main.ScreenToViewportPoint(mousePos);
        switch (packageData.packageConfig.checkMode)
        {
            case PaperManager.CheckMode.None:
                break;
            case PaperManager.CheckMode.WindowArea:
                isEnterView = IsHitCardObject(mousePos);
                break;
            case PaperManager.CheckMode.Accurate:
                break;
            case PaperManager.CheckMode.HighAccurate:
                break;
            default:
                break;
        }

        if (packageData.packageConfig.focus_effect)
        {
            if (isEnterView)
            {
                if (!isfocus)
                {
                    isfocus = true;
                    currentTargetScale = focus_scale;
                    currentTargetShadowAlpha = 1;
                }
                Focus(mousePos);
                Render.material.SetVector("mpos", new Vector4(viewpos.x - 0.5f, viewpos.y - 0.5f, 0, 0));
            }
            else
            {
                isfocus = false;
                currentTargetScale = start_scale;
                currentTargetShadowAlpha = 0.8f;

                float rx = Mathf.Sin(Time.time * 0.128f) * 0.5f;
                float ry = -0.3f;
                Render.material.SetVector("mpos", new Vector4(rx, ry, 0, 0));

            }

            transform.localScale = Vector3.Lerp(transform.localScale, Vector3.one * currentTargetScale, .2f);

            currentShadowAlpha = Mathf.Lerp(currentShadowAlpha, currentTargetShadowAlpha, 10 * Time.deltaTime);
            Render.material.SetFloat("_ShadowStrngth", currentShadowAlpha);
        }

        //实时缩放容忍度调节
        scale_tolorence = AppDataManager.Instance.GetCurrentPackageInfo().packageConfig.scaling_tolerance;
        // Debug.Log(img_plane_startscale);
        transform.Find("Image").localScale = img_plane_startscale * (scale_tolorence / start_scale_tolorence);

    }

    public virtual void OnUpdateAmp(float amp)
    {
       Render.material.SetFloat("_Amount", amp);
    }

    protected virtual void ReleaseResouces()
    {
        Destroy(lastTex);
        lastTex = null;
    }

    private void OnDestroy()
    {
        ReleaseResouces();
    }

}
